/// <reference path="../Resources/js/jquery/jquery.debug.js" />
/// <reference name="MicrosoftAjax.debug.js" />

function MBasis() {
    ///	<summary locid="T:J#MBasis">
    ///	This is a class that holds data about base definitions of MForm items.
    /// All MForm items must be registered within their corresponding basis.
    /// The basis also takes care of the parent-child relationship between MForm items.
    ///	</summary>
    MBasis.initializeBase(this, []);
    this.children = new Array();
    this.instances = new Object();        
}

MBasis.prototype = {
    set_rootId: function(id) {
        /// <summary>
        /// sets the MForm root id
        /// </summary>  
        this.rootId = id;
    },

    get_rootId: function() {
        /// <returns type="string" >
        /// returns the MForm root id       
        /// </returns>
        return this.rootId;
    },

    set_id: function(id) {
        /// <summary>
        /// sets the basis prototype id
        /// </summary>
        this.prototypeId = id;
    },

    get_id: function() {
        /// <returns type="string" >
        /// returns the basis prototype id - the prototype id is filled with 0's in place of MForm item position locators
        /// </returns>
        return this.prototypeId;
    },

    set_minOccurs: function(minOccurs) {
        /// <summary>
        /// sets the basis minimal occurs
        /// </summary>
        this.minOccurs = minOccurs;
    },

    get_minOccurs: function() {
        /// <returns type="number" >
        /// returns the basis minimal occurs
        /// </returns>
        return this.minOccurs;
    },

    set_maxOccurs: function(maxOccurs) {
        /// <summary>
        /// sets the basis maximal occurs
        /// </summary>
        this.maxOccurs = maxOccurs;
    },

    get_maxOccurs: function() {
        /// <returns type="number" >
        /// returns the basis maximal occurs
        /// </returns>
        return this.maxOccurs;
    },

    set_last: function(last) {
        this.last = last;
    },

    get_last: function() {
        return this.last;
    },

    getMForm: function() {
        /// <summary>
        /// returns the root MForm object
        /// </summary>    
        /// <returns type="MForm" >
        /// the the root MForm object
        /// </returns>
        return $find(this.get_rootId());
    },

    initialize: function() {
        MBasis.callBaseMethod(this, 'initialize');
        this.getMForm().elements[this.prototypeId] = this;
        this.determineParent();
    },

    setPrototypeNode: function(node) {
        /// <summary>
        /// sets the prototype node that will be cloned when new elements are added
        /// </summary>   
        this.node = node;
    },

    dispose: function() {
        MBasis.callBaseMethod(this, 'dispose');
        delete this.node;
        for (var key in this.instances) {
            this.instances[key].dispose();
            delete this.instances[key];
        }
        delete this.instances;
        if (this.descriptor != null) {
            this.descriptor.unload();
            delete this.descriptor;
        }
        delete this.parent;
    },

    determineParent: function() {
        this.parent = MBasis.get((new Path(this.prototypeId)).getParentPath());
        if (this.parent == null) {
            this.isRoot = true;
        } else {
            this.parent.children[this.parent.children.length] = this;
        }
    },

    getName: function() {
        return this.node.getAttribute("name");
    },

    getInstances: function(id) {
        var instances = new Array();
        for (var key in this.instances) {
            if (id == null || key.startsWith(id)) {
                instances[instances.length] = this.instances[key];
            }
        }
        return instances;
    },

    getSiblings: function(id) {
        un_id = Path.getUnindexedId(id);
        var siblings = new Array();
        for (var key in this.instances) {
            if (key.startsWith(un_id)) {
                siblings[siblings.length] = this.instances[key];
            }
        }
        return siblings;
    },

    getInstance: function(id) {
        var path = new Path(id);
        return this.instances[path.getNodePath()];
    },

    createInstance: function(node) {
        this.instances[node.id] = MItem.create(node, this);
        return this.instances[node.id];
    },

    removeInstance: function(id) {
        var instance = this.instances[id];
        delete this.instances[id];
        instance.raiseUnloaded();
    },

    incrementAvailableIndex: function(id) {
        var availableIndex = $("*[name = '" + Path.getUnindexedId(id) + "']")[0];
        availableIndex.value = (parseInt(availableIndex.value) + 1).toString();
    },

    getAvailableIndex: function(id) {
        var availableIndex = $("*[name = '" + Path.getUnindexedId(id) + "']")[0];
        return (parseInt(availableIndex.value) + 1).toString();
    },

    register: function(node) {
        var elems = $(node).find('.' + MItem.Element).andSelf();
        for (var i = 0; i < elems.length; i++) {
            MBasis.getById(elems[i].id).registerSingle(elems[i]);
        }
    },

    registerSingle: function(node) {
        this.createInstance(node);
    },

    unregister: function(node) {
        this.removeInstance(node.id);
        this.getMForm().unregisterBases(node);
    }
}

MBasis.registerClass("MBasis", Sys.Component);


MBasis.get = function(id) {
    if (id == null || id == "") return null;
    var mform = MForm.getById(id);
    if (!mform || !mform.elements) return null;
    return mform.elements[id];
}

MBasis.getById = function(id) {
    var idPath = new Path(id);
    var prototypeId = idPath.getPrototypePath();
    return MBasis.get(prototypeId);
}

MBasis.removeNode = function(node) {
    var idPath = new Path(node.id);
    var prototypeId = idPath.getPrototypePath();
    var mform = MForm.getById(prototypeId);
    var mElemBasis = mform.elements[prototypeId];
    if (mElemBasis && mElemBasis.instances[node.id]) {
        mElemBasis.removeInstance(node.id);
    }
}

MBasis.add = function(initialId) {
    var idPath = new Path(initialId);
    var prototypeId = idPath.getPrototypePath();
    var mform = MForm.getById(prototypeId);
    var basisElement = mform.elements[prototypeId];
    if (!basisElement) {
        return;
    }
    var parent = null;
    var addList = new Array();
    while (parent == null) {
        addList[addList.length] = idPath.getNodePath();
        var pp = idPath.getParentPath();
        var parent = MItem.getById(pp);
        idPath = new Path(pp);
    }
    var last;
    for (var i = addList.length - 1; i >= 0; i--) {
        last = Path.getLast(addList[i]);
        parent = parent.add(last);
    }
    return parent;
}